/* 
	exportfile (vfs_file_path, hard_disk_path) – Export the file from the file 
	system into the hard disk. 
	exportfile is intended to be able to pull the file out irrespective of 
	whether it is text file or not. The output file should be created by simply 
	dumping contents of the block into the output file as an uninterpreted 
	blob of bytes.
*/

#include <stdio.h>
#include <string.h>
#include "..//include//createvfs.h"
#include "..//include//n_ary.h"
#include "..//include//vfs_errorcodes.h"

int exportfileop(char filepath[], char outputfile[], char filename_g[]) {
	
	struct Block b;
	struct header headervar;
	struct FD file_desc;

	FILE *fp;
	FILE *fexp;

	char str[100], newstr1[100], newstr2[100], node_label[100], abspath[100];
	int num, j = 0, level = 0, count = 1, pos = 1, i, k = 0;
	int bnum;
	char fdpath[100];
	
	if ((strcmp(filepath,"") == 0) || (strcmp(outputfile,"") == 0)) {
		printf("exportfile_FAILURE %s\n",ERR_VFS_EXPORTFILE_00);
		return 0;
	}
	
	
	
	
	// extension to be taken care of
	//if ()
	
	
	
	
	
	else {
		/*
			Traversing n-ary tree to search a file/ folder based on pathname
			and returning the corresponding node to the user.
		*/
	   Tree cur_tree;   
	   Tree prev_tree;
	   Tree sib=cur_tree;
	   Tree new;
	   NODE first=NULL;   
	   NODE cur=first;
	   NODE last;

	   // Split the path based on '/'
	   while(filepath[pos]!='\0'){
			 strcat(abspath,"/");	
			 j=0;
			 num=splitexp(filepath,pos);
			 if(num>(strlen(filepath)-1)) 
			 	num = strlen(filepath)-1;
			 for(i=pos; i<=num; i++){
			 	newstr2[j]=filepath[i];
				j++;
		   	 }
		   	 newstr2[j]='\0';    
		   	 strcat(abspath,newstr2); 
		   	 first=insert_rear_ll(newstr2,abspath,first);
		   	 //strcat(abspath,newstr2);
		     if(num>=strlen(filepath)-1) 
		     	break;
		     pos=num+2;
	   }

	   last=cur;
	   cur=first;
	   while(cur->next!=NULL) {
		   count=count+1;
		   cur=cur->next;
	   }   
	
	   cur=first;
	   cur_tree=root->left;
	   sib=root->left;
	   prev_tree=root;     
	   while(count > 0){														// count = 1 => leaf node
	   		if(cur_tree!=NULL){ 
			   	if(strcmp(cur_tree->node_label,cur->entry) == 0 && count!=1){  // if (the two strings are equal) {...}
		        	cur=cur->next;
		       		prev_tree=cur_tree;
					cur_tree=cur_tree->left;
					sib=cur_tree;
					count=count-1;
		   		}
		   		else if(strcmp(cur_tree->node_label,cur->entry) == 0 && count==1){
		   			count = count-1;
		   		}
		   		else {	// traverse to the right siblings
		   			prev_tree = cur_tree;
		   			cur_tree = cur_tree -> right;
		   		}
		   	}
		   	else {
					printf("exportfile_FAILURE %s\n",ERR_VFS_EXPORTFILE_01);      
					return 0;
		   	}
	    }
		
		// cur_tree is the node to be exported
		strcpy(fdpath,"");
		strcat(fdpath,cur_tree->path);
		strcat(fdpath,cur_tree->node_label);
			
		// vfs file is opened to goto the corresponding file descriptor
		fp = fopen(filename_g, "rb+");
		if(fp==NULL) {
			printf("exportfile_FAILURE %s\n",ERR_VFS_EXPORTFILE_01);
		 	return 0;
		}
	
		rewind(fp);
		fread(&headervar, sizeof(struct header), 1, fp);

		// seek to the start of FD block
		rewind(fp);
		fseek(fp, LABEL_SIZE*sizeof(char) + 2*(sizeof(int)), SEEK_SET); 
			
		i=0;
		while(i < headervar.total_desc) {
			fread(&file_desc, sizeof(struct FD), 1, fp);
			if (strcmp(file_desc.path,fdpath) == 0) {
				bnum = file_desc.blockno;
				// bnum will give the offset factor to the respective data block
				break;
			}
			i++;
		}
			 		
		// seek to the respective data block
		rewind(fp);
		fseek(fp, sizeof(struct header)+sizeof(int)*num_blocks, SEEK_SET);
		  		
		// fseek to the desired block number
		fseek(fp, 1024 * (bnum-1), SEEK_CUR);

		// reading the block
	 	fread(&b,1024,1,fp);
		
		// open output file for writing
		fexp = fopen(outputfile,"w");
	  	if (fexp == NULL) {
	  		printf("exportfile_FAILURE %s\n",ERR_VFS_EXPORTFILE_02);
		  	return 0;
		}
		fwrite(&b, sizeof(struct Block),1,fexp);
	}
	
	fclose(fp);
	fclose(fexp);
	return 1;

}

int splitexp(char *str,int pos){
   int j,i;
   j=0;
   for(i=pos; i<strlen(str);i++){
      if(str[i]=='/' || str[i]=='"') return i-1;
   }
   
   return i;
}
